package com.book.oauth.server.user.controller;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.book.common.api.core.RESTfulMethod;
import com.book.common.api.entity.CurrentUser;
import com.book.common.api.helper.TransformHelper;
import com.book.common.result.Failed;
import com.book.common.result.PageInfo;
import com.book.common.result.RestResponse;
import com.book.common.result.Success;
import com.book.modules.annotation.InjectionCurrentUser;
import com.book.modules.core.controller.BaseController;
import com.book.oauth.server.user.dto.UserDto;
import com.book.oauth.server.user.entity.User;
import com.book.oauth.server.user.service.IUserService;
import com.book.oauth.server.user.vo.UserVo;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * Description：
 *
 * @Author： leo.xiong
 * @CreateDate： 2020-04-26
 * @Email： leo.xiong@suyun360.com
 * @Version:
 */
@Slf4j
@Validated
@RestController
@Api(value = "用户信息")
@RequestMapping(value = "${adminPath}/user")
public class UserController extends BaseController {

    @Autowired
    private IUserService userService;

    /**
     * 根据ID获取用户信息
     *
     * @param id
     * @param currentUser
     * @return
     */
    @GetMapping(value = "{id}", consumes = "application/json")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "根据id获取用户信息", httpMethod = RESTfulMethod.GET, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true)
    })
    @PreAuthorize("hasRole('ROLE_USER') OR hasRole('ROLE_ADMIN')")
    public RestResponse get(@NotBlank(message = "{required}") @PathVariable String id, @ApiIgnore CurrentUser currentUser) {
        try {
            if (StringUtils.isEmpty(id)) {
                return new Failed("BOOK:CORE:10016", i18nHelper.get("BOOK:CORE:10016"));
            }
            return new Success(this.userService.getById(id), i18nHelper.get("BOOK:CORE:10014", "USER"));
        } catch (Exception e) {
            log.error("查询用户失败", e);
            return new Failed("BOOK:CORE:10017", i18nHelper.get("BOOK:CORE:10017", "USER"));
        }
    }

    /**
     * 查询用户信息
     *
     * @param userDto
     * @param currentUser
     * @return
     */
    @PostMapping(value = "list")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "查询用户信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    public RestResponse list(@RequestBody UserDto userDto, @ApiIgnore CurrentUser currentUser) {
        try {
            User user = TransformHelper.transform(userDto, User.class);
            List<User> userList = this.userService.findAllList(user);
            return new Success(TransformHelper.transformList(userList, UserVo.class), i18nHelper.get("BOOK:CORE:10014", "USER"));
        } catch (Exception e) {
            log.error("查询用户失败", e);
            return new Failed("BOOK:CORE:10018", i18nHelper.get("BOOK:CORE:10018", "USER"));
        }
    }

    /**
     * 查询用户信息
     *
     * @param userDto
     * @param currentUser
     * @return
     */
    @PostMapping(value = "page/list")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "查询用户分页信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    public RestResponse pageList(@RequestBody UserDto userDto, @ApiIgnore CurrentUser currentUser) {
        try {
            User user = TransformHelper.transform(userDto, User.class);
            PageInfo<User> page = new PageInfo(userDto.getPageNo(), userDto.getPageSize());
            page = this.userService.findPageList(user, page);
            return new Success(TransformHelper.transformPage(page, UserVo.class), i18nHelper.get("BOOK:COMMON:10004"));
        } catch (Exception e) {
            log.error("分页查询用户失败", e);
            return new Failed("BOOK:COMMON:10007", i18nHelper.get("BOOK:COMMON:10007") + e.getMessage());
        }
    }

    /**
     * 新增用户信息
     *
     * @param userDto
     * @param currentUser
     * @return
     */
    @PostMapping(value = "save")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "保存用户信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    public RestResponse save(@Valid @RequestBody UserDto userDto, @ApiIgnore CurrentUser currentUser) {
        try {
            this.userService.save(TransformHelper.transform(userDto, User.class));
            return new Success("", i18nHelper.get("BOOK:COMMON:10008"));
        } catch (Exception e) {
            log.error("新增用户失败", e);
            return new Failed("BOOK:COMMON:10009", i18nHelper.get("BOOK:COMMON:10009") + e.getMessage());
        }
    }

    /**
     * 修改用户信息
     *
     * @param userDto
     * @param currentUser
     * @return
     */
    @PutMapping(value = "update")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "修改用户信息", httpMethod = RESTfulMethod.PUT, response = Success.class)
    public RestResponse update(@Valid @RequestBody UserDto userDto, @ApiIgnore CurrentUser currentUser) {
        try {
            if (userDto == null || userDto.getId() == null) {
                return new Failed("BOOK:COMMON:10010", i18nHelper.get("BOOK:COMMON:10010"));
            }
            this.userService.update(Wrappers.update(TransformHelper.transform(userDto, User.class)));
            return new Success(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改用户失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }

    /**
     * 删除用户信息
     *
     * @param id
     * @param currentUser
     * @return
     */
    @DeleteMapping(value = "delete/{id}")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "根据ID删除用户信息", httpMethod = RESTfulMethod.DELETE, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true)
    })
    public RestResponse delete(@NotBlank(message = "{required}") @PathVariable String id, @ApiIgnore CurrentUser currentUser) {
        try {
            this.userService.removeByIds(Lists.newArrayList(id.split(StringPool.COMMA)));
            return new Success("", i18nHelper.get("BOOK:COMMON:10013"));
        } catch (Exception e) {
            log.error("删除用户失败", e);
            return new Failed("BOOK:COMMON:10014", i18nHelper.get("BOOK:COMMON:10014") + e.getMessage());
        }
    }

    /**
     * 导出用户模板信息
     *
     * @param currentUser
     * @return
     */
    @PostMapping(value = "export/template")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "导出用户模板信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    public RestResponse exportTemplate(@ApiIgnore CurrentUser currentUser) {
        try {
            super.excelHelper.exportExcel("用户", UserVo.class);
            return new Success("", i18nHelper.get("BOOK:COMMON:10015"));
        } catch (Exception e) {
            log.error("导出用户模板信息失败", e);
            return new Failed("BOOK:COMMON:10016", i18nHelper.get("BOOK:COMMON:10016") + e.getMessage());
        }
    }

    /**
     * 导出用户信息
     *
     * @param userDto
     * @param currentUser
     * @return
     */
    @PostMapping(value = "export/excel")
    @ResponseBody
    @InjectionCurrentUser
    @ApiOperation(value = "导出用户信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    public RestResponse exportExcel(@RequestBody UserDto userDto, @ApiIgnore CurrentUser currentUser) {
        try {
            List<User> userList = this.userService.findAllList(TransformHelper.transform(userDto, User.class));
            super.excelHelper.exportExcel("用户", UserVo.class, TransformHelper.transformList(userList, UserVo.class));
            return new Success("", i18nHelper.get("BOOK:COMMON:10024"));
        } catch (Exception e) {
            log.error("导出用户信息失败", e);
            return new Failed("BOOK:COMMON:10025", i18nHelper.get("BOOK:COMMON:10025") + e.getMessage());
        }
    }

    /**
     * 导入用户信息
     *
     * @param filePath
     * @param currentUser
     * @return
     */
    @PostMapping(value = "import/excel")
    @ResponseBody
    @ApiOperation(value = "导入用户信息", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filePath", value = "文件路径", required = true)
    })
    public RestResponse importExcel(@RequestParam(value = "filePath") String filePath, @ApiIgnore CurrentUser currentUser) {
        try {
            List<UserVo> userVoList = super.excelHelper.importExcel(filePath, UserVo.class);
            if (CollectionUtils.isEmpty(userVoList)) {
                return new Failed("BOOK:COMMON:10026", i18nHelper.get("BOOK:COMMON:10026"));
            }
            this.userService.saveBatch(TransformHelper.transformList(userVoList, User.class));
            return new Success("", i18nHelper.get("BOOK:COMMON:10027"));
        } catch (Exception e) {
            log.error("导入用户信息失败", e);
            return new Failed("BOOK:COMMON:10028", i18nHelper.get("BOOK:COMMON:10028") + e.getMessage());
        }
    }


    @PostMapping(value = "update/login/time")
    @ResponseBody
    @ApiOperation(value = "修改登录时间，保存登录日志", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true),
            @ApiImplicitParam(name = "userName", value = "用户名", required = true),
            @ApiImplicitParam(name = "ip", value = "IP地址", required = true),
            @ApiImplicitParam(name = "location", value = "登录地点", required = true),
            @ApiImplicitParam(name = "browser", value = "浏览器", required = true),
            @ApiImplicitParam(name = "systemInfo", value = "系统类型", required = true)
    })
    public RestResponse<String> updateLoginTime(String userId, String userName, String location, String ip, String browser, String systemInfo) {
        try {
            userService.updateLoginTime(userId, userName, location, ip, browser, systemInfo);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改登录时间错误", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }

    /**
     * 根据Id重置密码
     *
     * @param id
     */
    @ApiOperation(value = "重置密码", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ResponseBody
    @PostMapping("reset/password")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true)
    })
    public RestResponse<String> resetPassword(Long id) {
        try {
            userService.resetPassword(id);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("充值密码失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }

    /**
     * 修改密码
     *
     * @param id
     * @param oldPassword
     * @param password
     */
    @PostMapping(value = "update/password")
    @ResponseBody
    @ApiOperation(value = "修改密码", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true),
            @ApiImplicitParam(name = "oldPassword", value = "老密码", required = true),
            @ApiImplicitParam(name = "password", value = "新密码", required = true)
    })
    public RestResponse<String> updatePassword(Long id, String oldPassword, String password) {
        try {
            userService.updatePassword(id, oldPassword, password);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }

    /**
     * 修改头像信息
     *
     * @param id
     * @param avatar
     */
    @PostMapping(value = "update/avatar")
    @ResponseBody
    @ApiOperation(value = "修改头像", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true),
            @ApiImplicitParam(name = "avatar", value = "头像", required = true)
    })
    public RestResponse<String> updateAvatar(Long id, String avatar) {
        try {
            userService.updateAvatar(id, avatar);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改头像失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }


    /**
     * 修改主题信息
     *
     * @param id
     * @param theme
     */
    @PostMapping(value = "update/theme")
    @ResponseBody
    @ApiOperation(value = "修改主题", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true),
            @ApiImplicitParam(name = "theme", value = "主题", required = true)
    })
    public RestResponse<String> updateTheme(Long id, String theme) {
        try {
            userService.updateTheme(id, theme);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改主题失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }

    /**
     * 修改tab信息
     *
     * @param id
     * @param isTab
     */
    @PostMapping(value = "update/tab")
    @ResponseBody
    @ApiOperation(value = "修改tab", httpMethod = RESTfulMethod.POST, response = Success.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true),
            @ApiImplicitParam(name = "isTab", value = "是否打开tab", required = true)
    })
    public RestResponse<String> updateTab(Long id, String isTab) {
        try {
            userService.updateTab(id, isTab);
            return Success.buildSuccess(i18nHelper.get("BOOK:COMMON:10011"));
        } catch (Exception e) {
            log.error("修改tab失败", e);
            return new Failed("BOOK:COMMON:10012", i18nHelper.get("BOOK:COMMON:10012") + e.getMessage());
        }
    }
}
